
package jstella.cart;

import dolmisani.toys.emulators.j2600.cart.Cartridge;

/**
 * Cartridge class used for Atari's 8K bankswitched games. There are two 4K
 * banks.
 *
 * @author Bradford W. Mott
 * @version $Id: CartridgeF8.java,v 1.2 2007/08/12 04:51:29 mauvila Exp $
 */
public class CartridgeF8 extends Cartridge {

    private final static long serialVersionUID = 3629215127350071982L;
    private int myCurrentBank = 0;
    private int myResetBank = 0;
    //private int[] cartridgeImage = new int[8192];

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    public CartridgeF8(byte[] imageBytes, boolean swapbanks) {

        md5Digest = calculateMD5Digest(imageBytes);
        cartridgeImage = toIntArray(imageBytes);

        // Normally bank 1 is the reset bank, unless we're dealing with ROMs
        // that have been incorrectly created with banks in the opposite order
        myResetBank = swapbanks ? 0 : 1;
    }

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    public void reset() {
        // Upon reset we switch to the reset bank
        setCurrentBank((char) myResetBank);
    }

    public void install(jstella.core.JSSystem system) {
        this.system = system;

        // Map ROM image into the system
        addIndirectAccess(0x1FF8, 0x2000);

        setCurrentBank(1);
    }

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    public int peek(int address) {
        int zNewAddress = address & 0x0FFF;

        // Switch banks if necessary
        switch (zNewAddress) {
            case 0x0FF8:
                // Set the current bank to the lower 4k bank
                setCurrentBank(0);
                break;

            case 0x0FF9:
                // Set the current bank to the upper 4k bank
                setCurrentBank(1);
                break;

            default:
                break;
        }

        return cartridgeImage[(myCurrentBank * 4096) + zNewAddress];
    }

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    public void poke(int address, int aByteValue) {
        int zNewAddress = address & 0x0FFF;

        // Switch banks if necessary
        switch (zNewAddress) {
            case 0x0FF8:
                // Set the current bank to the lower 4k bank
                setCurrentBank(0);
                break;

            case 0x0FF9:
                // Set the current bank to the upper 4k bank
                setCurrentBank(1);
                break;

            default:
                break;
        }
    }

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    protected void setCurrentBank(int bank) {
        if (bankLockedFlag) {
            return;
        }


        myCurrentBank = bank;



        addDirectPeekAccess(0x1000, 0x1FF8, cartridgeImage, 0x0FFF, myCurrentBank * 4096);  // Map ROM image into the system

    }

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    protected int getCurrentBank() {
        return myCurrentBank;
    }

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    protected int bankCount() {
        return 2;
    }

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    public boolean patch(int address, int aValue) {
        address &= 0xfff;
        cartridgeImage[myCurrentBank * 4096 + address] = aValue;
        setCurrentBank(myCurrentBank);
        return true;
    }
}
